﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Web;

namespace Gonte.Web.Handlers
{
    /// <summary>
    /// Generates a JSON object from an embedded resource
    /// 
    /// Steps:
    /// 1 - Create the resources:
    ///     a - Add the ASP.NET folder App_GlobalResources
    ///     b - Set the build option to "Embedded Resource"
    /// 2 - Add the handler
    ///     a - Add the following code to the HTTP handler section
    ///     <add verb="GET,POST"
    ///       path="*.jsr" 
    ///       type="Gonte.Web.Handlers.ResourcesToJsonHandler, Gonte.Web"/>
    ///     b - Add a reference to Gonte.Web dll
    ///     c - In a case of an MVC application add the following code to the Global.asax:
    ///     routes.IgnoreRoute("{filename}.jsr");
    /// 3 - Add the call on the page you want the resource to be returned
    ///     <script src="Gonte.Web.TestMvcApp$App_GlobalResources.AppResources.jsr" type="text/javascript"></script>
    ///     
    ///     where:
    ///     - Gonte.Web.TestMvcApp is the namespace where  and ALSO
    ///     the name of the web dll
    ///     - the '$' sign is the delimiter of the path to the resource
    ///     - the part after the '$' sign is the path to the resource
    ///     
    ///     If the name of the dll is different from the namespace then the following script can be used:
    ///         <script src="Gonte.Web.TestMvcApp.App_GlobalResources.AppResources.jsr?assemblyName=Gonte.Web.TestMvcApp" type="text/javascript"></script>
    ///         
    ///     In this case there is no '$' sign and the name of the dll is specified as a parameter
    ///     Set the full resource name as the name of the handler
    /// </summary>
    public class ResourcesToJsonHandler 
        : IHttpHandler
    {
        /// <summary>
        /// You will need to configure this handler in the web.config file of your 
        /// web and register it with IIS before being able to use it. For more information
        /// see the following link: http://go.microsoft.com/?linkid=8101007
        /// </summary>
        #region IHttpHandler Members

        public bool IsReusable
        {
            get { return false; }
        }

        public void ProcessRequest(HttpContext context)
        {
            HttpRequest request = context.Request;

            // Get the name of the resource
            string resourceName = request.FilePath;
            int lastDot = resourceName.LastIndexOf('.');
            resourceName = resourceName.Substring(1, lastDot - 1); // starts at 1 to remove the starting slash '/'

            string assemblyName = null;

            int separator = resourceName.IndexOf('$'); // Separates the name of the assembly from the location of the resource

            if (separator > -1)
            {
                assemblyName = resourceName.Substring(0, separator);
                resourceName = resourceName.Replace('$', '.'); // Make the resource name recognizable
            }
            else // The assembly name must be passed as a parameter
            {
                assemblyName = request["assemblyName"];
                PreCondition.RequireNotNullOrEmpty(assemblyName, "assemblyName");
            }

            string content = ResourcesToJsonConverter.GetResourceAsJson(
                context,
                resourceName,
                () =>
                {
                    assemblyName += ","; // Make sure we search the full name

                    // Find the assembly for that resource
                    AppDomain appDomain = AppDomain.CurrentDomain;
                    Assembly[] loadedAssemblies = AppDomain.CurrentDomain.GetAssemblies();

                    return loadedAssemblies.FirstOrDefault(asm => asm.FullName.StartsWith(assemblyName));
                });

            HttpResponse response = context.Response;
            response.AppendHeader("Content-Length", content.Length.ToString());
            response.ContentType = "text/javascript";  
            response.Write(content);
            response.Flush();  
        }

        #endregion
    }
}
